package gemini;

import aries.Configuration;
import aries.Locales;
import aries.Setting;
import aries.database.Database;
import aries.database.DatabaseConfiguration;
import aries.database.Query;
import aries.database.Table;
import aries.security.Validation;
import aries.utils.ExceptionManager;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Wizard extends JFrame {

    //Variable declaration
    /**
     * Locales variable.
     */
    Locales locales = new Locales(Setting.getLanguage(Setting.ENGLISH_US));
    
    /**
     * Called form when the wizard finish.
     */
    private JFrame frame;
    
    /**
     * Generated table.
     */
    private Table[] table;
    
    /**
     * The size of frame.
     */
    private Dimension frameSize = new Dimension(640, 480);
    
    /**
     * Clear parameter.
     */
    public static final byte DATABASE = 0;
    
    //Component declaration
    private JPanel pnHome = new JPanel(null);
    private JPanel pnDatabase = new JPanel(null);
    private JPanel pnFinish = new JPanel(null);
    private JLabel lbWelcome = new JLabel(locales.getText("wizard.welcome"));
    private JLabel lbIntro = new JLabel(locales.getText("wizard.introduction"));
    private JLabel lbWelcomeDb = new JLabel(locales.getText("wizard.database.welcome"));
    private JLabel lbIntroDb = new JLabel(locales.getText("wizard.database.introduction"));
    private JLabel lbWelcomeFn = new JLabel(locales.getText("wizard.finish.welcome"));
    private JLabel lbIntroFn = new JLabel(locales.getText("wizard.finish.introduction"));
    private JLabel lbProduct = new JLabel(locales.getText("wizard.product")+":");
    private JLabel lbIp = new JLabel(locales.getText("wizard.ip")+":");
    private JLabel lbPort = new JLabel(locales.getText("wizard.port")+":");
    private JLabel lbDbName = new JLabel(locales.getText("wizard.dbname")+":");
    private JLabel lbUser = new JLabel(locales.getText("wizard.user")+":");
    private JLabel lbPwd = new JLabel(locales.getText("wizard.pass")+":");
    private JLabel lbExIp = new JLabel("("+locales.getText("wizard.example")+" localhost)");
    private JLabel lbExPort = new JLabel("("+locales.getText("wizard.example")+" 3306)");
    private JLabel lbExDbName = new JLabel("("+locales.getText("wizard.example")+" mysql)");
    private JLabel lbExUser = new JLabel("("+locales.getText("wizard.example")+" root)");
    private JLabel lbProcess1 = new JLabel(locales.getText("wizard.configuration"));
    private JLabel lbProcess2 = new JLabel(locales.getText("wizard.database"));
    private JLabel lbProcess3 = new JLabel(locales.getText("wizard.table"));
    private JLabel lbStatus1 = new JLabel(locales.getText("wizard.not.complete"));
    private JLabel lbStatus2 = new JLabel(locales.getText("wizard.not.complete"));
    private JLabel lbStatus3 = new JLabel(locales.getText("wizard.not.complete"));
    private JTextField txIp = new JTextField();
    private JTextField txPort = new JTextField("1251");
    private JTextField txDbName = new JTextField();
    private JTextField txUser = new JTextField();
    private JTextField txPwd = new JTextField();
    private JButton btExit = new JButton(locales.getText("wizard.exit"));
    private JButton btNext = new JButton(locales.getText("wizard.next"));
    private JButton btPrevDb = new JButton(locales.getText("wizard.previous"));
    private JButton btNextDb = new JButton(locales.getText("wizard.next"));
    private JButton btPrevFinish = new JButton(locales.getText("wizard.previous"));
    private JButton btFinish = new JButton(locales.getText("wizard.finish"));
    private JComboBox cbProduct = new JComboBox();
    
    
    public Wizard(JFrame home, Table[] table) {
        Interface.nativeLook();
        initComponents();
        this.setSize(frameSize);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setTitle("Aries Wizard");
        Interface.center(this);
        
        //Showing home panel on start
        hideAllPanel();
        pnHome.setVisible(true);
        btFinish.setEnabled(false);
        
        this.frame = home;
        this.table = table;
    }
    
    public Wizard(JFrame home, Table[] table, byte lang) {
        Interface.nativeLook();
        this.locales = new Locales(Setting.getLanguage(lang));
        initComponents();
        this.setSize(frameSize);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setTitle("Aries Wizard");
        Interface.center(this);
        
        //Showing home panel on start
        hideAllPanel();
        pnHome.setVisible(true);
        btFinish.setEnabled(false);
        
        this.frame = home;
        this.table = table;
    }
    
    private void initComponents() {
        //Home init
        pnHome.setSize(frameSize);
        lbWelcome.setBounds(10, 10, 500, 30);
        lbWelcome.setFont(new Font("Verdana", Font.BOLD, 24));
        lbIntro.setBounds(15, 40, 600, 30);
        lbIntro.setFont(new Font("Verdana", Font.PLAIN, 13));
        btExit.setBounds(10, 410, 100, 30);
        btExit.setFont(new Font("Verdana", Font.PLAIN, 11));
        btExit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                System.exit(0);
            }
        });
        btNext.setBounds(530, 410, 100, 30);
        btNext.setFont(new Font("Verdana", Font.PLAIN, 11));
        btNext.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                hideAllPanel();
                pnDatabase.setVisible(true);
            }
        });
        pnHome.add(lbWelcome);
        pnHome.add(lbIntro);
        pnHome.add(btExit);
        pnHome.add(btNext);
        getContentPane().add(pnHome);
        
        //Database init
        pnDatabase.setSize(frameSize);
        lbWelcomeDb.setBounds(10, 10, 500, 30);
        lbWelcomeDb.setFont(new Font("Verdana", Font.BOLD, 24));
        lbIntroDb.setBounds(15, 40, 600, 30);
        lbIntroDb.setFont(new Font("Verdana", Font.PLAIN, 13));
        lbProduct.setBounds(20, 75, 100, 30);
        lbProduct.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbIp.setBounds(20, 105, 100, 30);
        lbIp.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbPort.setBounds(20, 135, 100, 30);
        lbPort.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbDbName.setBounds(20, 165, 100, 30);
        lbDbName.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbUser.setBounds(20, 195, 100, 30);
        lbUser.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbPwd.setBounds(20, 225, 100, 30);
        lbPwd.setFont(new Font("Verdana", Font.PLAIN, 11));
        cbProduct.setBounds(120, 80, 300, 20);
        cbProduct.setFont(new Font("Verdana", Font.PLAIN, 11));//, "IBM DB2", "Microsoft Access", "SQLite", "Microsoft SQL Server", "Pointbase Embedded Server", "Cloudscape", "Cloudscape RMI", "Firebird", "Microsoft SQL Server JTurbo", "Microsoft SQL Server Sprinta", "Microsoft SQL Server 2000", "PostgreSQL 6.5 and earlier", "PostgreSQL 7 and later", "Instant DB 3.13 and earlier", "Instant DB 3.14 and later", "HypersonicSQL 1.2 and earlier", "HypersonicSQL 1.3 and later" 
        cbProduct.setModel(new DefaultComboBoxModel(new String[] { "Oracle", "MySQL"}));
        cbProduct.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                if (cbProduct.getSelectedIndex() == 0) {
                    clear(DATABASE);
                    txPort.setText("1251");
                    txDbName.setEditable(false);
                } else if (cbProduct.getSelectedIndex() == 1) {
                    clear(DATABASE);
                    txPort.setText("3306");
                    txUser.setText("root");
                    txDbName.setEditable(true);
                } else {
                    clear(DATABASE);
                    txDbName.setEditable(true);
                }
            }
        });
        txIp.setBounds(120, 110, 300, 20);
        txIp.setFont(new Font("Verdana", Font.PLAIN, 11));
        txPort.setBounds(120, 140, 300, 20);
        txPort.setFont(new Font("Verdana", Font.PLAIN, 11));
        txDbName.setBounds(120, 170, 300, 20);
        txDbName.setFont(new Font("Verdana", Font.PLAIN, 11));
        txDbName.setEditable(false);
        txUser.setBounds(120, 200, 300, 20);
        txUser.setFont(new Font("Verdana", Font.PLAIN, 11));
        txPwd.setBounds(120, 230, 300, 20);
        txPwd.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbExIp.setBounds(450, 110, 300, 20);
        lbExIp.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbExPort.setBounds(450, 140, 300, 20);
        lbExPort.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbExDbName.setBounds(450, 170, 300, 20);
        lbExDbName.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbExUser.setBounds(450, 200, 300, 20);
        lbExUser.setFont(new Font("Verdana", Font.PLAIN, 11));
        btPrevDb.setBounds(10, 410, 100, 30);
        btPrevDb.setFont(new Font("Verdana", Font.PLAIN, 11));
        btPrevDb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                hideAllPanel();
                pnHome.setVisible(true);
                clear(DATABASE);
            }
        });
        btNextDb.setBounds(530, 410, 100, 30);
        btNextDb.setFont(new Font("Verdana", Font.PLAIN, 11));
        btNextDb.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                checkDb();
            }
        });
        pnDatabase.add(lbWelcomeDb);
        pnDatabase.add(lbIntroDb);
        pnDatabase.add(lbProduct);
        pnDatabase.add(lbIp);
        pnDatabase.add(lbPort);
        pnDatabase.add(lbDbName);
        pnDatabase.add(lbUser);
        pnDatabase.add(lbPwd);
        pnDatabase.add(cbProduct);
        pnDatabase.add(txIp);
        pnDatabase.add(txPort);
        pnDatabase.add(txDbName);
        pnDatabase.add(txUser);
        pnDatabase.add(txPwd);
        pnDatabase.add(lbExIp);
        pnDatabase.add(lbExPort);
        pnDatabase.add(lbExDbName);
        pnDatabase.add(lbExUser);
        pnDatabase.add(btNextDb);
        pnDatabase.add(btPrevDb);
        getContentPane().add(pnDatabase);
        
        //Finish init
        pnFinish.setSize(frameSize);
        lbWelcomeFn.setBounds(10, 10, 500, 30);
        lbWelcomeFn.setFont(new Font("Verdana", Font.BOLD, 24));
        lbIntroFn.setBounds(15, 40, 600, 30);
        lbIntroFn.setFont(new Font("Verdana", Font.PLAIN, 13));
        lbProcess1.setBounds(20, 70, 200, 30);
        lbProcess1.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbProcess2.setBounds(20, 100, 200, 30);
        lbProcess2.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbProcess3.setBounds(20, 130, 200, 30);
        lbProcess3.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbStatus1.setBounds(410, 70, 150, 30);
        lbStatus1.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbStatus2.setBounds(410, 100, 150, 30);
        lbStatus2.setFont(new Font("Verdana", Font.PLAIN, 11));
        lbStatus3.setBounds(410, 130, 150, 30);
        lbStatus3.setFont(new Font("Verdana", Font.PLAIN, 11));
        pnFinish.addComponentListener(new ComponentListener() {
            @Override
            public void componentResized(ComponentEvent ce) {
            }

            @Override
            public void componentMoved(ComponentEvent ce) {
            }

            @Override
            public void componentShown(ComponentEvent ce) {
                Database.setIp(txIp.getText());
                Database.setPort(txPort.getText());
                Database.setDbName(txDbName.getText());
                Database.setUser(txUser.getText());
                Database.setPass(txPwd.getText());
                Database.setProduct((byte) cbProduct.getSelectedIndex());
                Configuration dc = new DatabaseConfiguration(DatabaseConfiguration.get(DatabaseConfiguration.TITLE), 
                                   DatabaseConfiguration.get(DatabaseConfiguration.VALUE));
                try {
                    dc.generate();
                    lbStatus1.setText(locales.getText("wizard.complete"));
                } catch (Exception ex) {
                    lbStatus1.setText(locales.getText("wizard.failed"));
                    ExceptionManager.addException(ex);
                }
                try {
                    if ((byte) cbProduct.getSelectedIndex() != 0) { 
                        String temp = txDbName.getText();
                        if ((byte) cbProduct.getSelectedIndex() == 1) {
                            Database.setDbName("mysql");
                        }
                        Query.createDatabase(txDbName.getText());
                        Database.setDbName(temp);
                    }
                    lbStatus2.setText(locales.getText("wizard.complete"));
                } catch (Exception ex) {
                    System.out.println(ex.getMessage());
                    lbStatus2.setText(locales.getText("wizard.failed"));
                    ExceptionManager.addException(ex);
                }
                try {
                    for (byte i=0; i<table.length; i++) {
                        Query.createTable(new Table(table[i].getTable()), table[i].getField());
                    }
                    lbStatus3.setText(locales.getText("wizard.complete"));
                } catch (Exception ex) {
                    lbStatus3.setText(locales.getText("wizard.failed"));
                    ExceptionManager.addException(ex);
                }
                btFinish.setEnabled(true);
            }

            @Override
            public void componentHidden(ComponentEvent ce) {
            }
        });
        btPrevFinish.setBounds(10, 410, 100, 30);
        btPrevFinish.setFont(new Font("Verdana", Font.PLAIN, 11));
        btPrevFinish.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                hideAllPanel();
                pnDatabase.setVisible(true);
            }
        });
        btFinish.setBounds(530, 410, 100, 30);
        btFinish.setFont(new Font("Verdana", Font.PLAIN, 11));
        btFinish.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                finish();
            }
        });
        pnFinish.add(lbWelcomeFn);
        pnFinish.add(lbIntroFn);
        pnFinish.add(lbProcess1);
        pnFinish.add(lbProcess2);
        pnFinish.add(lbProcess3);
        pnFinish.add(lbStatus1);
        pnFinish.add(lbStatus2);
        pnFinish.add(lbStatus3);
        pnFinish.add(btPrevFinish);
        pnFinish.add(btFinish);
        getContentPane().add(pnFinish);
    }
    
    /**
     * Check database configuration input.
     */
    private void checkDb() {
        if (Validation.isEmpty(cbProduct, 0) || Validation.isEmpty(txIp, "") || 
            Validation.isEmpty(txPort, "") || Validation.isEmpty(txDbName, "") || 
            Validation.isEmpty(txUser, "")) {
            JOptionPane.showMessageDialog(null, locales.getText("wizard.message"));
        } else {
            hideAllPanel();
            pnFinish.setVisible(true);
        }
    }
    
    /**
     * Finish the wizard.
     */
    private void finish() {
        this.dispose();
        frame.setVisible(true);
    }
    
    /**
     * Hiding all panel.
     */
    private void hideAllPanel() {
        pnHome.setVisible(false);
        pnDatabase.setVisible(false);
        pnFinish.setVisible(false);
    }
    
    /**
     * Clear all field in specified form.
     * 
     * @param form 
     */
    private void clear(byte form) {
        if (form == DATABASE) {
            txIp.setText("");
            txPort.setText("");
            txDbName.setText("");
            txDbName.setEditable(true);
            txUser.setText("");
            txPwd.setText("");
        }
    }
    
}
